/**
 * Copyright (c) 2012, http://www.yissugames.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.yissugames.blocklife.gamelogic;

import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.Color;
import org.newdawn.slick.TrueTypeFont;
import org.newdawn.slick.opengl.Texture;

import com.yissugames.blocklife.ContentLoader;
import com.yissugames.blocklife.RenderSystem;

public class Inventory {
	
	private Texture quickbar_grid;
	private Texture quickbar_text;
	private Texture quickbar_selected;
	private Texture inventory_grid;
	private TrueTypeFont font;
	
	private StackInfo[] quickbar = new StackInfo[10];
	private StackInfo[][] inventory = new StackInfo[10][8];
	private CraftingWindow crafting = new CraftingWindow();
	
	private int selectedQuickItem = 0;
	
	private boolean isFullInventoryOpened = false;
	private boolean lastIState = false;
	private boolean lastLeftMouseState = false;
	private boolean lastRightMouseState = false;
	
	private StackInfo onMouse = null;
	
	public boolean isFullInventoryOpened() {
		return isFullInventoryOpened;
	}

	public Inventory()
	{
		quickbar_grid = ContentLoader.getTexture("quickbar.grid");
		quickbar_text = ContentLoader.getTexture("quickbar.text");
		quickbar_selected = ContentLoader.getTexture("quickbar.grid.select");
		inventory_grid = ContentLoader.getTexture("inventory.grid");
		//font = ContentLoader.getExternFont("font001", 22);
		font = ContentLoader.getFont("Arial", 0, 12);
		
		if(quickbar_grid == null || quickbar_text == null)
			System.exit(1);
	}
	
	public int removeCurrentQuick()
	{
		int id = -1;
		
		if(quickbar[selectedQuickItem] != null)
		{
			id = quickbar[selectedQuickItem].getId();
			if(quickbar[selectedQuickItem].getCount() - 1 == 0)
				quickbar[selectedQuickItem] = null;
			else
				quickbar[selectedQuickItem].setCount(quickbar[selectedQuickItem].getCount() - 1);
		}
		
		return id;
	}
	
	public void addItem(int id, int count)
	{
		if(id == -1 || count == -1)
			return;
		
		//System.out.println("Add " + count + " from type " + id);
		
		for(StackInfo info: quickbar)
		{
			if(info != null) {
				if(info.getId() == id)
					count = info.add(count);
				
				if(count == 0)
					return;
			}
		}
		for(StackInfo[] infos: inventory)
		{
			for(StackInfo info: infos)
			{
				if(info != null) {
					if(info.getId() == id)
						count = info.add(count);
					
					if(count == 0)
						return;
				}
			}
		}
		
		int i = 0;
		for(StackInfo info: quickbar)
		{
			if(info == null)
			{
				quickbar[i] = new StackInfo(id, count > 255 ? 255: count);
				if(count > 255)
					count -= 255;
				else
					return;
			}
			i++;
		}
		
		int x = 0, y = 0;
		for(StackInfo[] infos: inventory)
		{
			for(StackInfo info: infos)
			{
				if(info == null)
				{
					inventory[x][y] = new StackInfo(id, count > 255 ? 255: count);
					if(count > 255)
						count -= 255;
					else
						return;
				}
				y++;
			}
			x++;
			y = 0;
		}
	}
	
	/**
	 * Important draw at last!
	 */
	public void render()
	{
		GL11.glLoadIdentity(); 	// Reset matrix
		
		if(Keyboard.isKeyDown(Keyboard.KEY_0)) selectedQuickItem = 9;
		if(Keyboard.isKeyDown(Keyboard.KEY_1)) selectedQuickItem = 0;
		if(Keyboard.isKeyDown(Keyboard.KEY_2)) selectedQuickItem = 1;
		if(Keyboard.isKeyDown(Keyboard.KEY_3)) selectedQuickItem = 2;
		if(Keyboard.isKeyDown(Keyboard.KEY_4)) selectedQuickItem = 3;
		if(Keyboard.isKeyDown(Keyboard.KEY_5)) selectedQuickItem = 4;
		if(Keyboard.isKeyDown(Keyboard.KEY_6)) selectedQuickItem = 5;
		if(Keyboard.isKeyDown(Keyboard.KEY_7)) selectedQuickItem = 6;
		if(Keyboard.isKeyDown(Keyboard.KEY_8)) selectedQuickItem = 7;
		if(Keyboard.isKeyDown(Keyboard.KEY_9)) selectedQuickItem = 8;
		if(Keyboard.isKeyDown(Keyboard.KEY_I) && !lastIState) isFullInventoryOpened = !isFullInventoryOpened;
		lastIState = Keyboard.isKeyDown(Keyboard.KEY_I);
		
		if(Mouse.hasWheel())
		{
			int wheel = Mouse.getDWheel();
			if(wheel > 0)
				selectedQuickItem++;
			if(wheel < 0)
				selectedQuickItem--;
			if(selectedQuickItem > 9) 
				selectedQuickItem = 0;
			if(selectedQuickItem < 0)
				selectedQuickItem = 9;
		}
		
		RenderSystem.renderTexture(quickbar_grid, 5, 5);
		
		int i = 0;
		for(StackInfo info: quickbar)
		{
			if(info != null)
			{
				RenderSystem.renderTileTexture(ContentLoader.getTexture("texture"), i * 34 + 9, 9, 28, 28, info.id);
				font.drawString(i * 34 + 9, 6, Integer.toString(info.getCount()), Color.white);
			}
			i++;
		}
		
		int mouseX = Mouse.getX();
		int mouseY = Display.getHeight() - Mouse.getY() - 1;
		
		if(isFullInventoryOpened)
		{
			RenderSystem.renderTexture(inventory_grid, 5, 39);
			
			for(int x = 0; x < 10; x++) {
				for(int y = 0; y < 8; y++) {
					StackInfo info = inventory[x][y];
					if(info != null)
					{
						RenderSystem.renderTileTexture(ContentLoader.getTexture("texture"), x * 34 + 9, y * 34 + 43, 28, 28, info.id);
						font.drawString( x * 34 + 9, y * 34 + 40, Integer.toString(info.getCount()), Color.white);
					}
				}
			}
			
			crafting.render();
		}
		
		RenderSystem.renderTexture(quickbar_selected, selectedQuickItem * 34 + 5, 5);
		
		// Enable inventory & quickbar selection with mouse
		if(isFullInventoryOpened)
		{
			for(int x = 0; x < 10; x++) {
				for(int y = 0; y < 9; y++) {
					if(mouseX > x * 34 + 5 && mouseX < (x+ 1) * 34 + 5 &&
							mouseY > y * 34 + 5 && mouseY < (y + 1) * 34 + 5)
					{
						RenderSystem.renderTexture(quickbar_selected, x * 34 + 5, y * 34 + 5);
						if(Mouse.isButtonDown(0) && !lastLeftMouseState) // get full stack
						{
							if(y == 0) // Quickbar
							{
								if(onMouse != null)
								{
									if(quickbar[x] == null) // is null
									{
										quickbar[x] = onMouse;
										onMouse = null;
									} else if(quickbar[x].id == onMouse.id) // is the same
									{
										int rest = quickbar[x].add(onMouse.count);
										if(rest == 0)
											onMouse = null;
										else
											onMouse.count = rest;
									}
								} else {
									onMouse = quickbar[x];
									quickbar[x] = null;
								}
							} else { // Inventory
								if(onMouse != null)
								{
									if(inventory[x][y - 1] == null) // is null
									{
										inventory[x][y - 1] = onMouse;
										onMouse = null;
									} else if(inventory[x][y - 1].id == onMouse.id) // is the same
									{
										int rest = inventory[x][y - 1].add(onMouse.count);
										if(rest == 0)
											onMouse = null;
										else
											onMouse.count = rest;
									}
								} else {
									onMouse = inventory[x][y - 1];
									inventory[x][y - 1] = null;
								}
							}
						} else if(Mouse.isButtonDown(1) && !lastRightMouseState) // get one
						{
							if(y == 0) // quickbar
							{
								if(quickbar[x] != null)
								{
									if(onMouse == null) {
										onMouse = new StackInfo(quickbar[x].id, 1);
										quickbar[x].count--;
										if(quickbar[x].count == 0) // remove then count 0
											quickbar[x] = null;
									} else if(onMouse.id == quickbar[x].id) {
										int count = onMouse.add(1);
										if(count != 1)
											quickbar[x].count --;
										if(quickbar[x].count == 0) // remove then count 0
											quickbar[x] = null;
									}
								}
							} else {
								if(inventory[x][y - 1] != null)
								{
									if(onMouse == null) {
										onMouse = new StackInfo(inventory[x][y - 1].id, 1);
										inventory[x][y - 1].count--;
										if(inventory[x][y - 1].count == 0) // remove then count 0
											inventory[x][y - 1] = null;
									} else if(onMouse.id == inventory[x][y - 1].id) {
										int count = onMouse.add(1);
										if(count != 1)
											inventory[x][y - 1].count --;
										if(inventory[x][y - 1].count == 0) // remove then count 0
											inventory[x][y - 1] = null;
									}
								}
							}
						}
					}
				}
			}
			
			onMouse = crafting.update(onMouse);
		}
		
		RenderSystem.renderTexture(quickbar_text, 5, 5);
		
		if(onMouse != null) {  
			RenderSystem.renderTileTexture(ContentLoader.getTexture("texture"), mouseX, mouseY, 28, 28, onMouse.id);
			font.drawString(mouseX + 24 - font.getWidth(Integer.toString(onMouse.getCount())) / 2, mouseY - 2, Integer.toString(onMouse.getCount()), Color.white);
		}
		
		lastLeftMouseState = Mouse.isButtonDown(0);
		lastRightMouseState = Mouse.isButtonDown(1);
	}
	
	public static class StackInfo
	{
		private int id;
		private int count = 0;
		
		public StackInfo(int id, int count)
		{
			this.id = id;
			this.count = count;
		}
		
		public int add(int count)
		{
			int tmpCount = this.count + count;
			if(tmpCount > 255)
			{
				this.count = 255;
				return tmpCount - 255;
			}
			else
			{
				this.count = tmpCount;
				return 0;
			}
		}
		
		public int getId()
		{
			return this.id;
		}
		
		public int getCount()
		{
			return this.count;
		}
		
		public void setCount(int count)
		{
			this.count = count;
		}
		
		@Override
		public String toString()
		{
			return this.id + ";" + this.count;
		}
	}
	
}
